package handler

import (
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/lab-online/internal/class/constant"
	"github.com/lab-online/internal/class/entity"
	"github.com/lab-online/pkg/auth"
	mw "github.com/lab-online/pkg/middleware"
	"github.com/lab-online/pkg/resp"
)

type CreateClassReqBody struct {
	Name        string `json:"name" binding:"required,max=64,min=1" example:"班级名称"`         // 班级名称
	Description string `json:"description" binding:"required,min=1,max=256" example:"班级描述"` // 班级描述
	CourseID    uint   `json:"courseID" binding:"required,min=1" example:"1"`               // 课程id
	Teacher     string `json:"teacher" binding:"required,min=3,max=8" example:"20240204"`   // 教师工号
}

var CreateClassValidator = mw.NewValidator(func() *mw.ValidatorOptions {
	return &mw.ValidatorOptions{
		Body: &CreateClassReqBody{},
	}
})

type CreateClassRespData struct {
	ID          uint   `json:"id" binding:"required" example:"1"`                           // 班级id
	Name        string `json:"name" binding:"required,max=64,min=1" example:"班级名称"`         // 班级名称
	Description string `json:"description" binding:"required,min=1,max=256" example:"班级描述"` // 班级描述
	CourseID    uint   `json:"courseID" binding:"required,min=1" example:"1"`               // 课程id
	Teacher     string `json:"teacher" binding:"required,min=3,max=8" example:"20240204"`   // 教师工号
}

type CreateClassRespBody struct {
	resp.BaseRespBody
	Data CreateClassRespData `json:"data" binding:"required"`
}

// CreateClass 创建班级
//
//	@Summary				创建班级
//	@Description			## 规则
//	@Description			教师可以创建 `teacher` 为自己的班级，管理员可以创建任何班级
//	@Description.markdown	CreateClass
//	@Tags					class
//	@Accept					json
//	@Produce				json
//	@Security				bearer
//	@Param					Authorization	header		string				true	"`teacher` | `admin`"
//	@Param					class			body		CreateClassReqBody	true	"班级信息"
//	@Success				201				{object}	CreateClassRespBody
//	@header					201				{string}	Location	"班级地址 `/v1/classes/1`"
//	@Failure				400				{object}	resp.FailedRespBodyString
//	@Failure				403				{object}	resp.FailedRespBodyString
//	@Failure				500				{object}	resp.FailedRespBodyString
//	@x-apifox-status		"developing"
//	@Router					/v1/classes	[post]
func (h *Handler) CreateClass(c *gin.Context) {
	class := c.MustGet(mw.KeyBody).(*CreateClassReqBody)
	authEntity := c.MustGet(auth.KeyAuth).(auth.AuthEntity)

	classEntity := entity.NewClassEntity(
		entity.WithName(class.Name),
		entity.WithDescription(class.Description),
		entity.WithCourseID(class.CourseID),
		entity.WithTeacher(class.Teacher),
	)

	if savedClass, err := h.domain.CreateClass(classEntity, authEntity); err != nil {
		resp.ErrorHandler(c, err)
	} else {
		c.Header("Location", fmt.Sprintf("/v1/classes/%d", savedClass.GetID()))
		resp.Created(c, constant.CodeCreateClassSuccess, &CreateClassRespData{
			ID:          savedClass.GetID(),
			Name:        savedClass.GetName(),
			Description: savedClass.GetDescription(),
			CourseID:    savedClass.GetCourseID(),
			Teacher:     savedClass.GetTeacher(),
		})
	}
}
